| @@ -0,0 +1,40 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | + | |
| 3 | +# Generated by Django 3.2.16 on 2024-03-27 07:50 | |
| 4 | + | |
| 5 | +from django.db import migrations, models | |
| 6 | + | |
| 7 | + | |
| 8 | +class Migration(migrations.Migration): | |
| 9 | + | |
| 10 | + dependencies = [ | |
| 11 | +        ('account', '0060_auto_20240312_1350'), | |
| 12 | + ] | |
| 13 | + | |
| 14 | + operations = [ | |
| 15 | + migrations.CreateModel( | |
| 16 | + name='LensmanIntegralIncomeExpensesInfo', | |
| 17 | + fields=[ | |
| 18 | +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |
| 19 | +                ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')), | |
| 20 | +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')), | |
| 21 | +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')), | |
| 22 | +                ('user_id', models.CharField(blank=True, db_index=True, help_text='用户唯一标识', max_length=32, null=True, verbose_name='user_id')), | |
| 23 | +                ('brand_id', models.CharField(blank=True, db_index=True, help_text='品牌唯一标识', max_length=32, null=True, verbose_name='brand_id')), | |
| 24 | +                ('brand_name', models.CharField(blank=True, help_text='品牌名称', max_length=255, null=True, verbose_name='brand_name')), | |
| 25 | +                ('integral', models.IntegerField(default=0, help_text='增减积分', verbose_name='integral')), | |
| 26 | +                ('remark', models.CharField(blank=True, help_text='备注', max_length=255, null=True, verbose_name='remark')), | |
| 27 | +                ('activity_id', models.CharField(blank=True, db_index=True, help_text='活动唯一标识', max_length=32, null=True, verbose_name='activity_id')), | |
| 28 | +                ('expired_at', models.DateField(blank=True, help_text='积分过期日期', null=True, verbose_name='expired_at')), | |
| 29 | + ], | |
| 30 | +            options={ | |
| 31 | + 'verbose_name': 'lensmanintegralincomeexpensesinfo', | |
| 32 | + 'verbose_name_plural': 'lensmanintegralincomeexpensesinfo', | |
| 33 | + }, | |
| 34 | + ), | |
| 35 | + migrations.AddField( | |
| 36 | + model_name='lensmaninfo', | |
| 37 | + name='integral', | |
| 38 | + field=models.IntegerField(default=0, help_text='摄影师积分', verbose_name='integral'), | |
| 39 | + ), | |
| 40 | + ] | 
| @@ -383,6 +383,7 @@ class LensmanInfo(BaseModelMixin): | ||
| 383 | 383 |  | 
| 384 | 384 | name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'摄影师姓名') | 
| 385 | 385 | phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'摄影师联系电话') | 
| 386 | + integral = models.IntegerField(_(u'integral'), default=0, help_text=u'摄影师积分') | |
| 386 | 387 |  | 
| 387 | 388 | lensman_status = models.IntegerField(_(u'lensman_status'), choices=LENSMAN_STATUS, default=UNVERIFIED, help_text=u'摄影师状态', db_index=True) | 
| 388 | 389 |  | 
| @@ -412,6 +413,9 @@ class LensmanInfo(BaseModelMixin): | ||
| 412 | 413 | 'lensman_id': self.lensman_id, | 
| 413 | 414 | 'name': self.name, | 
| 414 | 415 | 'phone': self.phone, | 
| 416 | + 'start_date': self.start_date, | |
| 417 | + 'end_date': self.end_date, | |
| 418 | + 'integral': self.integral, | |
| 415 | 419 | 'is_expired': self.is_expired, | 
| 416 | 420 | 'lensman_status': self.lensman_status, | 
| 417 | 421 | } | 
| @@ -423,6 +427,7 @@ class LensmanInfo(BaseModelMixin): | ||
| 423 | 427 | 'user_id': self.user_id, | 
| 424 | 428 | 'name': self.name, | 
| 425 | 429 | 'phone': self.phone, | 
| 430 | + 'integral': self.integral, | |
| 426 | 431 | 'lensman_status': self.lensman_status, | 
| 427 | 432 | 'start_date': self.start_date, | 
| 428 | 433 | 'end_date': self.end_date, | 
| @@ -496,3 +501,54 @@ class UserIntegralIncomeExpensesInfo(BaseModelMixin): | ||
| 496 | 501 | 'created_at': tc.local_string(utc_dt=self.created_at), | 
| 497 | 502 | } | 
| 498 | 503 |  | 
| 504 | + | |
| 505 | +class LensmanIntegralIncomeExpensesInfo(BaseModelMixin): | |
| 506 | + user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) | |
| 507 | + | |
| 508 | + brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True) | |
| 509 | + brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称') | |
| 510 | + | |
| 511 | + integral = models.IntegerField(_(u'integral'), default=0, help_text=u'增减积分') | |
| 512 | + remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注') | |
| 513 | + | |
| 514 | + activity_id = models.CharField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True) | |
| 515 | + expired_at = models.DateField(_(u'expired_at'), blank=True, null=True, help_text=u'积分过期日期') | |
| 516 | + | |
| 517 | + class Meta: | |
| 518 | + verbose_name = _(u'lensmanintegralincomeexpensesinfo') | |
| 519 | + verbose_name_plural = _(u'lensmanintegralincomeexpensesinfo') | |
| 520 | + | |
| 521 | + def __unicode__(self): | |
| 522 | + return '%d' % self.pk | |
| 523 | + | |
| 524 | + @property | |
| 525 | + def admindata(self): | |
| 526 | + if self.activity_id: | |
| 527 | + act = MemberActivityInfo.objects.get(activity_id=self.activity_id) | |
| 528 | + else: | |
| 529 | + act = None | |
| 530 | + | |
| 531 | +        return { | |
| 532 | + 'integral': self.integral, | |
| 533 | + 'remark': self.remark, | |
| 534 | + 'act_info': act.admindata if act else None, | |
| 535 | + 'activity_id': self.activity_id, | |
| 536 | + 'expired_at': self.expired_at if self.expired_at else '', | |
| 537 | + 'created_at': tc.local_string(utc_dt=self.created_at), | |
| 538 | + } | |
| 539 | + | |
| 540 | + @property | |
| 541 | + def userdata(self): | |
| 542 | + if self.activity_id: | |
| 543 | + act = MemberActivityInfo.objects.get(activity_id=self.activity_id) | |
| 544 | + else: | |
| 545 | + act = None | |
| 546 | + | |
| 547 | +        return { | |
| 548 | + 'integral': self.integral, | |
| 549 | + 'remark': self.remark, | |
| 550 | + 'act_info': act.admindata if act else None, | |
| 551 | + 'activity_id': self.activity_id, | |
| 552 | + 'expired_at': self.expired_at if self.expired_at else '', | |
| 553 | + 'created_at': tc.local_string(utc_dt=self.created_at), | |
| 554 | + } | 
| @@ -2,13 +2,14 @@ | ||
| 2 | 2 |  | 
| 3 | 3 | from __future__ import division | 
| 4 | 4 |  | 
| 5 | +from django.conf import settings | |
| 5 | 6 | from django_logit import logit | 
| 6 | 7 | from django_response import response | 
| 7 | 8 | from django.db.models import Q | 
| 8 | 9 | from paginator import pagination | 
| 9 | 10 | from TimeConvert import TimeConvert as tc | 
| 10 | 11 |  | 
| 11 | -from account.models import LensmanInfo, UserIntegralIncomeExpensesInfo | |
| 12 | +from account.models import LensmanInfo, LensmanIntegralIncomeExpensesInfo | |
| 12 | 13 | from kodo.decorators import check_admin | 
| 13 | 14 |  | 
| 14 | 15 |  | 
| @@ -90,9 +91,36 @@ def lensman_integral_list(request, administrator): | ||
| 90 | 91 | except LensmanInfo.DoesNotExist: | 
| 91 | 92 | return response(200, 'Lensman Not Found', u'摄影师不存在') | 
| 92 | 93 |  | 
| 93 | - integrals = UserIntegralIncomeExpensesInfo.objects.filter(user_id=user_id, integral_from=UserIntegralIncomeExpensesInfo.LENSMAN_ACTIVITY, status=True) | |
| 94 | + integrals = LensmanIntegralIncomeExpensesInfo.objects.filter(user_id=user_id, status=True) | |
| 94 | 95 |  | 
| 95 | - integrals = [integral.lensman_admindata for integral in integrals] | |
| 96 | + integrals = [integral.admindata for integral in integrals] | |
| 96 | 97 |  | 
| 97 | 98 |  | 
| 98 | - return response(200, 'Get Lensman Integral List Success', u'获取摄影师积分列表成功', data=integrals) | |
| 99 | + return response(200, 'Get Lensman Integral List Success', u'获取摄影师积分列表成功', data=integrals) | |
| 100 | + | |
| 101 | + | |
| 102 | +@logit | |
| 103 | +def lensman_integral_update(request): | |
| 104 | +    user_id = request.POST.get('user_id', '') | |
| 105 | +    integral = int(request.POST.get('integral', 0)) | |
| 106 | +    remark = request.POST.get('remark', '') | |
| 107 | +    brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID | |
| 108 | + | |
| 109 | + try: | |
| 110 | + lensman = LensmanInfo.objects.get(user_id=user_id, status=True) | |
| 111 | + except LensmanInfo.DoesNotExist: | |
| 112 | + return response(200, 'Lensman Not Found', u'摄影师不存在') | |
| 113 | + | |
| 114 | + lensman.integral += integral | |
| 115 | + lensman.save() | |
| 116 | + | |
| 117 | + LensmanIntegralIncomeExpensesInfo.objects.create( | |
| 118 | + brand_id=brand_id, | |
| 119 | + user_id=user_id, | |
| 120 | + integral=integral, | |
| 121 | + remark=remark, | |
| 122 | + expired_at=lensman.end_date, | |
| 123 | + ) | |
| 124 | + | |
| 125 | + return response(200, 'Lensman Integral Update Success', u'摄影师积分更新成功') | |
| 126 | + | 
| @@ -2,10 +2,11 @@ | ||
| 2 | 2 |  | 
| 3 | 3 | from __future__ import division | 
| 4 | 4 |  | 
| 5 | +from django.conf import settings | |
| 5 | 6 | from django_logit import logit | 
| 6 | 7 | from django_response import response | 
| 7 | 8 |  | 
| 8 | -from account.models import LensmanInfo, UserIntegralIncomeExpensesInfo | |
| 9 | +from account.models import LensmanInfo, LensmanIntegralIncomeExpensesInfo | |
| 9 | 10 |  | 
| 10 | 11 | @logit | 
| 11 | 12 | def lensman_register(request): | 
| @@ -39,15 +40,16 @@ def lensman_detail(request): | ||
| 39 | 40 | @logit | 
| 40 | 41 | def lensman_integral_list(request): | 
| 41 | 42 |    user_id = request.POST.get('user_id', '') | 
| 43 | +  brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID | |
| 42 | 44 |  | 
| 43 | 45 | try: | 
| 44 | 46 | lensman = LensmanInfo.objects.get(user_id=user_id, status=True) | 
| 45 | 47 | except LensmanInfo.DoesNotExist: | 
| 46 | 48 | return response(200, 'Lensman Not Found', u'摄影师不存在') | 
| 47 | 49 |  | 
| 48 | - integrals = UserIntegralIncomeExpensesInfo.objects.filter(user_id=user_id, integral_from=UserIntegralIncomeExpensesInfo.LENSMAN_ACTIVITY, status=True) | |
| 50 | + integrals = LensmanIntegralIncomeExpensesInfo.objects.filter(user_id=user_id, status=True) | |
| 49 | 51 |  | 
| 50 | - integrals = [integral.lensman_userdata for integral in integrals] | |
| 52 | + integrals = [integral.userdata for integral in integrals] | |
| 51 | 53 |  | 
| 52 | 54 |  | 
| 53 | - return response(200, 'Get Lensman Integral List Success', u'获取摄影师积分列表成功', data=integrals) | |
| 55 | + return response(200, 'Get Lensman Integral List Success', u'获取摄影师积分列表成功', data=integrals) | 
| @@ -383,4 +383,5 @@ urlpatterns += [ | ||
| 383 | 383 | url(r'^admin/lensman/audit$', lensman_admin_views.lensman_audit, name='admin_lensman_audit'), | 
| 384 | 384 | url(r'^admin/lensman/update$', lensman_admin_views.lensman_update, name='admin_lensman_update'), | 
| 385 | 385 | url(r'^admin/lensman/integral/list$', lensman_admin_views.lensman_integral_list, name='admin_lensman_integral_list'), | 
| 386 | + url(r'^admin/lensman/integral/update$', lensman_admin_views.lensman_integral_update, name='admin_lensman_integral_update'), | |
| 386 | 387 | ] | 
| @@ -9,10 +9,9 @@ from django_response import response | ||
| 9 | 9 | from paginator import pagination | 
| 10 | 10 | from TimeConvert import TimeConvert as tc | 
| 11 | 11 |  | 
| 12 | -from account.models import UserIntegralIncomeExpensesInfo, UserInfo, LensmanInfo | |
| 13 | -from member.models import MemberActivityInfo, MemberActivitySignupInfo, MemberActivityContributionInfo, MemberActivityDataInfo | |
| 12 | +from member.models import MemberActivityInfo, MemberActivitySignupInfo, MemberActivityContributionInfo | |
| 14 | 13 | from kodo.decorators import check_admin | 
| 15 | -from utils.error.errno_utils import MemberActivityStatusCode, UserStatusCode | |
| 14 | +from utils.error.errno_utils import MemberActivityStatusCode | |
| 16 | 15 |  | 
| 17 | 16 |  | 
| 18 | 17 | @check_admin | 
| @@ -87,6 +86,8 @@ def activity_update(request, administrator): | ||
| 87 | 86 |      end_date = date = tc.to_date(request.POST.get('end_date', '') or settings.DEFAULT_END_DATE) | 
| 88 | 87 |      start_display_date = tc.to_date(request.POST.get('start_display_date', '') or settings.DEFAULT_START_DATE) | 
| 89 | 88 |      end_display_date = tc.to_date(request.POST.get('end_display_date', '') or settings.DEFAULT_END_DATE) | 
| 89 | +    start_data_submit_date = tc.to_date(request.POST.get('start_data_submit_date', '') or settings.DEFAULT_START_DATE) | |
| 90 | +    end_data_submit_date = tc.to_date(request.POST.get('end_data_submit_date', '') or settings.DEFAULT_END_DATE) | |
| 90 | 91 |      city = request.POST.get('city', '') | 
| 91 | 92 |      location = request.POST.get('location', '') | 
| 92 | 93 |      integral = int(request.POST.get('integral', 0)) | 
| @@ -128,6 +129,8 @@ def activity_update(request, administrator): | ||
| 128 | 129 | log.end_date = end_date | 
| 129 | 130 | log.start_display_date = start_display_date | 
| 130 | 131 | log.end_display_date = end_display_date | 
| 132 | + log.start_data_submit_date = start_data_submit_date | |
| 133 | + log.end_data_submit_date = end_data_submit_date | |
| 131 | 134 | log.city = city | 
| 132 | 135 | log.location = location | 
| 133 | 136 | log.integral = integral | 
| @@ -166,6 +169,8 @@ def activity_create(request, administrator): | ||
| 166 | 169 |      end_date = date = tc.to_date(request.POST.get('end_date', '') or settings.DEFAULT_END_DATE) | 
| 167 | 170 |      start_display_date = tc.to_date(request.POST.get('start_display_date', '') or settings.DEFAULT_START_DATE) | 
| 168 | 171 |      end_display_date = tc.to_date(request.POST.get('end_display_date', '') or settings.DEFAULT_END_DATE) | 
| 172 | +    start_data_submit_date = tc.to_date(request.POST.get('start_data_submit_date', '') or settings.DEFAULT_START_DATE) | |
| 173 | +    end_data_submit_date = tc.to_date(request.POST.get('end_data_submit_date', '') or settings.DEFAULT_END_DATE) | |
| 169 | 174 |      city = request.POST.get('city', '') | 
| 170 | 175 |      location = request.POST.get('location', '') | 
| 171 | 176 |      integral = int(request.POST.get('integral', 0)) | 
| @@ -201,6 +206,8 @@ def activity_create(request, administrator): | ||
| 201 | 206 | end_date=end_date, | 
| 202 | 207 | start_display_date=start_display_date, | 
| 203 | 208 | end_display_date=end_display_date, | 
| 209 | + start_data_submit_date=start_data_submit_date, | |
| 210 | + end_data_submit_date=end_data_submit_date, | |
| 204 | 211 | city=city, | 
| 205 | 212 | location=location, | 
| 206 | 213 | integral=integral, | 
| @@ -239,7 +246,7 @@ def activity_signup_list(request, administrator): | ||
| 239 | 246 |      num = int(request.POST.get('num', 20)) | 
| 240 | 247 |      query = request.POST.get('query', '') | 
| 241 | 248 |      is_signin = request.POST.get('is_signin', False) | 
| 242 | -    passed = request.POST.get('passed', '') | |
| 249 | +    audit_status = request.POST.get('audit_status', '') | |
| 243 | 250 |  | 
| 244 | 251 | logs = MemberActivitySignupInfo.objects.filter(activity_id=activity_id, status=True).exclude(fields='[]') | 
| 245 | 252 |  | 
| @@ -249,8 +256,8 @@ def activity_signup_list(request, administrator): | ||
| 249 | 256 | if is_signin: | 
| 250 | 257 | logs = logs.filter(is_signin=is_signin) | 
| 251 | 258 |  | 
| 252 | - if passed: | |
| 253 | - logs = logs.filter(passed=passed) | |
| 259 | + if audit_status: | |
| 260 | + logs = logs.filter(audit_status=audit_status) | |
| 254 | 261 |  | 
| 255 | 262 |  | 
| 256 | 263 | count = logs.count() | 
| @@ -262,70 +269,3 @@ def activity_signup_list(request, administrator): | ||
| 262 | 269 | 'count': count, | 
| 263 | 270 | 'left': left, | 
| 264 | 271 | }) | 
| 265 | - | |
| 266 | - | |
| 267 | -@check_admin | |
| 268 | -def activity_signup_pass(request, administrator): | |
| 269 | -    activity_id = request.POST.get('activity_id', '') | |
| 270 | -    signup_id = request.POST.get('signup_id', '') | |
| 271 | - | |
| 272 | - MemberActivitySignupInfo.objects.filter(activity_id=activity_id, signup_id=signup_id, status=True).update(passed=True) | |
| 273 | - | |
| 274 | - return response(200, 'Member Activity Signup Passed Success', u'活动报名通过成功') | |
| 275 | - | |
| 276 | - | |
| 277 | -@check_admin | |
| 278 | -def activity_data_list(request, administrator): | |
| 279 | -    activity_id = request.POST.get('activity_id', '') | |
| 280 | -    page = int(request.POST.get('page', 1)) | |
| 281 | -    num = int(request.POST.get('num', 20)) | |
| 282 | -    query = request.POST.get('query', '') | |
| 283 | - | |
| 284 | - logs = MemberActivityDataInfo.objects.filter(activity_id=activity_id, status=True) | |
| 285 | - if query: | |
| 286 | - logs = logs.filter(Q(lensman_name__icontains=query) | Q(lensman_phone__icontains=query)) | |
| 287 | - | |
| 288 | - count = logs.count() | |
| 289 | - logs, left = pagination(logs, page, num) | |
| 290 | - logs = [log.admindata for log in logs] | |
| 291 | - | |
| 292 | -    return response(200, 'Get Member Activity Data List Success', u'获取会员活动数据列表成功', data={ | |
| 293 | - 'logs': logs, | |
| 294 | - 'count': count, | |
| 295 | - 'left': left, | |
| 296 | - }) | |
| 297 | - | |
| 298 | -@check_admin | |
| 299 | -def activity_integral_add(request, administrator): | |
| 300 | -    activity_id = request.POST.get('activity_id', '') | |
| 301 | -    user_id = request.POST.get('user_id', '') | |
| 302 | -    lensman_id = request.POST.get('lensman_id', '') | |
| 303 | -    integral = int(request.POST.get('integral', 0)) | |
| 304 | -    remark = request.POST.get('remark', '') | |
| 305 | -    brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID | |
| 306 | - | |
| 307 | - try: | |
| 308 | - user = UserInfo.objects.get(user_id=user_id, status=True) | |
| 309 | - except UserInfo.DoesNotExist: | |
| 310 | - return response(UserStatusCode.USER_NOT_FOUND) | |
| 311 | - | |
| 312 | - try: | |
| 313 | - lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True) | |
| 314 | - except LensmanInfo.DoesNotExist: | |
| 315 | -        return response('400001', 'LensmanInfo Not Found', '摄影师不存在') | |
| 316 | - | |
| 317 | - user.integral += integral | |
| 318 | - user.save() | |
| 319 | - | |
| 320 | - UserIntegralIncomeExpensesInfo.objects.create( | |
| 321 | - brand_id=brand_id, | |
| 322 | - user_id=user_id, | |
| 323 | - integral_from=UserIntegralIncomeExpensesInfo.LENSMAN_ACTIVITY, | |
| 324 | - integral=integral, | |
| 325 | - final_integral=user.integral, | |
| 326 | - activity_id=activity_id, | |
| 327 | - remark=remark, | |
| 328 | - expired_at=lensman.end_date, | |
| 329 | - ) | |
| 330 | - | |
| 331 | - return response(200, 'Add Member Activity Integral Success', u'添加积分成功') | 
| @@ -129,54 +129,6 @@ def activity_signup_detail(request): | ||
| 129 | 129 |  | 
| 130 | 130 |  | 
| 131 | 131 | @logit | 
| 132 | -def activity_data_submit(request): | |
| 133 | -    user_id = request.POST.get('user_id', '') | |
| 134 | -    lensman_id = request.POST.get('lensman_id', '') | |
| 135 | -    activity_id = request.POST.get('activity_id', '') | |
| 136 | -    data_fields = request.POST.get('data_fields', '[]') | |
| 137 | - | |
| 138 | - try: | |
| 139 | - act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True) | |
| 140 | - except MemberActivityInfo.DoesNotExist: | |
| 141 | - return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND) | |
| 142 | - | |
| 143 | - try: | |
| 144 | - lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True) | |
| 145 | - except LensmanInfo.DoesNotExist: | |
| 146 | -        return response('400001', 'LensmanInfo Not Found', '摄影师不存在') | |
| 147 | - | |
| 148 | - if lensman.is_expired: | |
| 149 | - return response(40001, 'Lensman Has Expired', '摄影师合作已到期') | |
| 150 | - | |
| 151 | -    MemberActivityDataInfo.objects.update_or_create(user_id=user_id, activity_id=activity_id, defaults={ | |
| 152 | - 'title': act.title, | |
| 153 | - 'lensman_id': lensman_id, | |
| 154 | - 'lensman_name': lensman.name, | |
| 155 | - 'lensman_phone': lensman.phone, | |
| 156 | - 'data_fields': data_fields, | |
| 157 | - }) | |
| 158 | - | |
| 159 | -    return response(data={ | |
| 160 | - 'activity': act.data(user_id), | |
| 161 | - }) | |
| 162 | - | |
| 163 | - | |
| 164 | -@logit | |
| 165 | -def activity_data_detail(request): | |
| 166 | -    user_id = request.POST.get('user_id', '') | |
| 167 | -    activity_id = request.POST.get('activity_id', '') | |
| 168 | - | |
| 169 | - try: | |
| 170 | - data_info = MemberActivityDataInfo.objects.get(user_id=user_id, activity_id=activity_id, status=True) | |
| 171 | - except MemberActivityDataInfo.DoesNotExist: | |
| 172 | - return response() | |
| 173 | - | |
| 174 | -    return response(data={ | |
| 175 | - 'data_info': data_info.data, | |
| 176 | - }) | |
| 177 | - | |
| 178 | - | |
| 179 | -@logit | |
| 180 | 132 | def activity_contribute_create(request): | 
| 181 | 133 |      brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID | 
| 182 | 134 |      user_id = request.POST.get('user_id', '') | 
| @@ -2,7 +2,7 @@ | ||
| 2 | 2 |  | 
| 3 | 3 | from django.conf.urls import url | 
| 4 | 4 |  | 
| 5 | -from member import activity_admin_views | |
| 5 | +from member import activity_admin_views, lensman_activity_admin_views | |
| 6 | 6 |  | 
| 7 | 7 | # activity | 
| 8 | 8 | urlpatterns = [ | 
| @@ -15,11 +15,11 @@ urlpatterns = [ | ||
| 15 | 15 | # activity signup | 
| 16 | 16 | urlpatterns += [ | 
| 17 | 17 | url(r'^member/activity/signup/list$', activity_admin_views.activity_signup_list, name='admin_member_activity_signup_list'), | 
| 18 | - url(r'^member/activity/signup/pass$', activity_admin_views.activity_signup_pass, name='admin_member_activity_signup_pass'), | |
| 18 | + url(r'^member/activity/signup/audit$', lensman_activity_admin_views.activity_signup_audit, name='admin_member_activity_signup_audit'), | |
| 19 | 19 | ] | 
| 20 | 20 |  | 
| 21 | 21 | #activity data | 
| 22 | 22 | urlpatterns += [ | 
| 23 | - url(r'^member/activity/data/list$', activity_admin_views.activity_data_list, name='admin_member_activity_data_list'), | |
| 24 | - url(r'^member/activity/integral/add$', activity_admin_views.activity_integral_add, name='admin_member_activity_integral_add'), | |
| 23 | + url(r'^member/activity/data/list$', lensman_activity_admin_views.activity_data_list, name='admin_member_activity_data_list'), | |
| 24 | + url(r'^member/activity/integral/add$', lensman_activity_admin_views.activity_integral_add, name='admin_member_activity_integral_add'), | |
| 25 | 25 | ] | 
| @@ -0,0 +1,78 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | + | |
| 3 | +from django.conf import settings | |
| 4 | +from django.db.models import Q | |
| 5 | +from django_logit import logit | |
| 6 | +from django_response import response | |
| 7 | +from paginator import pagination | |
| 8 | + | |
| 9 | +from account.models import LensmanIntegralIncomeExpensesInfo, UserInfo, LensmanInfo | |
| 10 | +from member.models import MemberActivitySignupInfo, MemberActivityDataInfo | |
| 11 | +from kodo.decorators import check_admin | |
| 12 | +from utils.error.errno_utils import UserStatusCode | |
| 13 | + | |
| 14 | + | |
| 15 | +@check_admin | |
| 16 | +def activity_signup_audit(request, administrator): | |
| 17 | +    activity_id = request.POST.get('activity_id', '') | |
| 18 | +    signup_id = request.POST.get('signup_id', '') | |
| 19 | +    audit_status = request.POST.get('audit_status', 0) | |
| 20 | + | |
| 21 | + MemberActivitySignupInfo.objects.filter(activity_id=activity_id, signup_id=signup_id, status=True).update(audit_status=audit_status) | |
| 22 | + | |
| 23 | + return response(200, 'Member Activity Signup Audit Success', u'活动审核成功') | |
| 24 | + | |
| 25 | + | |
| 26 | +@check_admin | |
| 27 | +def activity_data_list(request, administrator): | |
| 28 | +    activity_id = request.POST.get('activity_id', '') | |
| 29 | +    page = int(request.POST.get('page', 1)) | |
| 30 | +    num = int(request.POST.get('num', 20)) | |
| 31 | +    query = request.POST.get('query', '') | |
| 32 | + | |
| 33 | + logs = MemberActivityDataInfo.objects.filter(activity_id=activity_id, status=True) | |
| 34 | + if query: | |
| 35 | + logs = logs.filter(Q(lensman_name__icontains=query) | Q(lensman_phone__icontains=query)) | |
| 36 | + | |
| 37 | + count = logs.count() | |
| 38 | + logs, left = pagination(logs, page, num) | |
| 39 | + logs = [log.admindata for log in logs] | |
| 40 | + | |
| 41 | +    return response(200, 'Get Member Activity Data List Success', u'获取会员活动数据列表成功', data={ | |
| 42 | + 'logs': logs, | |
| 43 | + 'count': count, | |
| 44 | + 'left': left, | |
| 45 | + }) | |
| 46 | + | |
| 47 | +@check_admin | |
| 48 | +def activity_integral_add(request, administrator): | |
| 49 | +    activity_id = request.POST.get('activity_id', '') | |
| 50 | +    user_id = request.POST.get('user_id', '') | |
| 51 | +    lensman_id = request.POST.get('lensman_id', '') | |
| 52 | +    integral = int(request.POST.get('integral', 0)) | |
| 53 | +    remark = request.POST.get('remark', '') | |
| 54 | +    brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID | |
| 55 | + | |
| 56 | + try: | |
| 57 | + user = UserInfo.objects.get(user_id=user_id, status=True) | |
| 58 | + except UserInfo.DoesNotExist: | |
| 59 | + return response(UserStatusCode.USER_NOT_FOUND) | |
| 60 | + | |
| 61 | + try: | |
| 62 | + lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True) | |
| 63 | + except LensmanInfo.DoesNotExist: | |
| 64 | +        return response('400001', 'LensmanInfo Not Found', '摄影师不存在') | |
| 65 | + | |
| 66 | + user.integral += integral | |
| 67 | + user.save() | |
| 68 | + | |
| 69 | + LensmanIntegralIncomeExpensesInfo.objects.create( | |
| 70 | + brand_id=brand_id, | |
| 71 | + user_id=user_id, | |
| 72 | + integral=integral, | |
| 73 | + activity_id=activity_id, | |
| 74 | + remark=remark, | |
| 75 | + expired_at=lensman.end_date, | |
| 76 | + ) | |
| 77 | + | |
| 78 | + return response(200, 'Add Member Activity Integral Success', u'添加积分成功') | 
| @@ -0,0 +1,82 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | + | |
| 3 | +from django.conf import settings | |
| 4 | +from django_logit import logit | |
| 5 | +from django.db.models import Q | |
| 6 | +from django_response import response | |
| 7 | + | |
| 8 | +from account.models import LensmanInfo | |
| 9 | +from member.models import MemberActivityInfo, MemberActivityDataInfo, MemberActivitySignupInfo | |
| 10 | +from utils.error.errno_utils import MemberActivityStatusCode | |
| 11 | + | |
| 12 | +@logit | |
| 13 | +def activity_data_submit(request): | |
| 14 | +    user_id = request.POST.get('user_id', '') | |
| 15 | +    lensman_id = request.POST.get('lensman_id', '') | |
| 16 | +    activity_id = request.POST.get('activity_id', '') | |
| 17 | +    data_fields = request.POST.get('data_fields', '[]') | |
| 18 | + | |
| 19 | + try: | |
| 20 | + act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True) | |
| 21 | + except MemberActivityInfo.DoesNotExist: | |
| 22 | + return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND) | |
| 23 | + | |
| 24 | + try: | |
| 25 | + lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True) | |
| 26 | + except LensmanInfo.DoesNotExist: | |
| 27 | +        return response('400001', 'LensmanInfo Not Found', '摄影师不存在') | |
| 28 | + | |
| 29 | + if lensman.is_expired: | |
| 30 | + return response(40001, 'Lensman Has Expired', '摄影师合作已到期') | |
| 31 | + | |
| 32 | +    MemberActivityDataInfo.objects.update_or_create(user_id=user_id, activity_id=activity_id, defaults={ | |
| 33 | + 'title': act.title, | |
| 34 | + 'lensman_id': lensman_id, | |
| 35 | + 'lensman_name': lensman.name, | |
| 36 | + 'lensman_phone': lensman.phone, | |
| 37 | + 'data_fields': data_fields, | |
| 38 | + }) | |
| 39 | + | |
| 40 | +    return response(data={ | |
| 41 | + 'activity': act.data(user_id), | |
| 42 | + }) | |
| 43 | + | |
| 44 | + | |
| 45 | +@logit | |
| 46 | +def activity_data_detail(request): | |
| 47 | +    user_id = request.POST.get('user_id', '') | |
| 48 | +    activity_id = request.POST.get('activity_id', '') | |
| 49 | + | |
| 50 | + try: | |
| 51 | + data_info = MemberActivityDataInfo.objects.get(user_id=user_id, activity_id=activity_id, status=True) | |
| 52 | + except MemberActivityDataInfo.DoesNotExist: | |
| 53 | + return response() | |
| 54 | + | |
| 55 | +    return response(data={ | |
| 56 | + 'data_info': data_info.data, | |
| 57 | + }) | |
| 58 | + | |
| 59 | + | |
| 60 | +@logit | |
| 61 | +def activity_signup_message(request): | |
| 62 | +    user_id = request.POST.get('user_id', '') | |
| 63 | + | |
| 64 | +    lensman_acts = MemberActivityInfo.objects.values_list('activity_id', flat=True).filter(activity_section=4, status=True) | |
| 65 | + infos = MemberActivitySignupInfo.objects.filter(Q(user_id=user_id) & Q(activity_id__in=lensman_acts) & Q(is_read=False)).exclude(audit_status=MemberActivitySignupInfo.UNAUDITED) | |
| 66 | + | |
| 67 | + infos = [info.data for info in infos] | |
| 68 | + | |
| 69 | +    return response(data={ | |
| 70 | + 'messages': infos | |
| 71 | + }) | |
| 72 | + | |
| 73 | +@logit | |
| 74 | +def activity_signup_message_read(request): | |
| 75 | +    user_id = request.POST.get('user_id', '') | |
| 76 | +    signup_id = request.POST.get('signup_id', '') | |
| 77 | + | |
| 78 | + MemberActivitySignupInfo.objects.filter(user_id=user_id, signup_id=signup_id).update(is_read=True) | |
| 79 | + | |
| 80 | + return response(200, 'Activity Signup Message Has Read Success', '活动报名消息已读') | |
| 81 | + | |
| 82 | + | 
| @@ -0,0 +1,44 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | + | |
| 3 | +# Generated by Django 3.2.16 on 2024-03-27 07:50 | |
| 4 | + | |
| 5 | +from django.db import migrations, models | |
| 6 | + | |
| 7 | + | |
| 8 | +class Migration(migrations.Migration): | |
| 9 | + | |
| 10 | + dependencies = [ | |
| 11 | +        ('member', '0069_auto_20240312_1350'), | |
| 12 | + ] | |
| 13 | + | |
| 14 | + operations = [ | |
| 15 | + migrations.RemoveField( | |
| 16 | + model_name='memberactivitysignupinfo', | |
| 17 | + name='passed', | |
| 18 | + ), | |
| 19 | + migrations.AddField( | |
| 20 | + model_name='memberactivityinfo', | |
| 21 | + name='end_data_submit_date', | |
| 22 | + field=models.DateField(blank=True, help_text='活动数据提交截止日期', null=True, verbose_name='end_data_submit_date'), | |
| 23 | + ), | |
| 24 | + migrations.AddField( | |
| 25 | + model_name='memberactivityinfo', | |
| 26 | + name='start_data_submit_date', | |
| 27 | + field=models.DateField(blank=True, help_text='活动数据提交开始日期', null=True, verbose_name='start_data_submit_date'), | |
| 28 | + ), | |
| 29 | + migrations.AddField( | |
| 30 | + model_name='memberactivitysignupinfo', | |
| 31 | + name='audit_status', | |
| 32 | + field=models.IntegerField(choices=[(0, '未审核'), (1, '已通过'), (2, '未通过')], db_index=True, default=0, help_text='审核状态', verbose_name='audit_status'), | |
| 33 | + ), | |
| 34 | + migrations.AddField( | |
| 35 | + model_name='memberactivitysignupinfo', | |
| 36 | + name='is_read', | |
| 37 | + field=models.BooleanField(default=False, help_text='报名消息是否已读', verbose_name='is_read'), | |
| 38 | + ), | |
| 39 | + migrations.AlterField( | |
| 40 | + model_name='memberactivityinfo', | |
| 41 | + name='activity_section', | |
| 42 | + field=models.IntegerField(choices=[(0, 'Tamron Life'), (1, 'Tamron LRC直播课'), (2, '会员投稿'), (3, '其他'), (4, '摄影师')], db_index=True, default=3, help_text='活动分区', verbose_name='activity_section'), | |
| 43 | + ), | |
| 44 | + ] | 
| @@ -379,7 +379,7 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin): | ||
| 379 | 379 | (1, u'Tamron LRC直播课'), | 
| 380 | 380 | (2, u'会员投稿'), | 
| 381 | 381 | (3, u'其他'), | 
| 382 | - (4, u'会员投稿'), | |
| 382 | + (4, u'摄影师'), | |
| 383 | 383 | ) | 
| 384 | 384 |  | 
| 385 | 385 | activity_id = ShortUUIDField(_(u'activity_id'), max_length=32, blank=True, help_text=u'活动唯一标识', db_index=True, unique=True) | 
| @@ -395,6 +395,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin): | ||
| 395 | 395 | end_date = models.DateField(_(u'end_date'), blank=True, null=True, help_text=u'活动报名截止日期') | 
| 396 | 396 | start_display_date = models.DateField(_(u'start_display_date'), blank=True, null=True, help_text=u'活动展示开始日期') | 
| 397 | 397 | end_display_date = models.DateField(_(u'end_display_date'), blank=True, null=True, help_text=u'活动展示截止日期') | 
| 398 | + start_data_submit_date = models.DateField(_(u'start_data_submit_date'), blank=True, null=True, help_text=u'活动数据提交开始日期') | |
| 399 | + end_data_submit_date = models.DateField(_(u'end_data_submit_date'), blank=True, null=True, help_text=u'活动数据提交截止日期') | |
| 398 | 400 |  | 
| 399 | 401 | city = models.CharField(_(u'city'), max_length=255, blank=True, default='', help_text=u'活动城市') | 
| 400 | 402 | location = models.CharField(_(u'location'), max_length=255, blank=True, default='', help_text=u'活动地点') | 
| @@ -507,7 +509,7 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin): | ||
| 507 | 509 | return MemberActivityContributionInfo.objects.filter(user_id=user_id, activity_id=self.activity_id, status=True).exists() | 
| 508 | 510 |  | 
| 509 | 511 | def is_signup_passed(self, user_id): | 
| 510 | - return MemberActivitySignupInfo.objects.filter(user_id=user_id, activity_id=self.activity_id, passed=True, status=True).exists() | |
| 512 | + return MemberActivitySignupInfo.objects.filter(user_id=user_id, activity_id=self.activity_id, audit_status=MemberActivitySignupInfo.PASSED, status=True).exists() | |
| 511 | 513 |  | 
| 512 | 514 | @property | 
| 513 | 515 | def welfares(self): | 
| @@ -544,6 +546,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin): | ||
| 544 | 546 | 'end_date': tc.local_date_string(self.end_date), | 
| 545 | 547 | 'start_display_date': tc.local_date_string(self.start_display_date), | 
| 546 | 548 | 'end_display_date': tc.local_date_string(self.end_display_date), | 
| 549 | + 'start_data_submit_date': tc.local_date_string(self.start_data_submit_date), | |
| 550 | + 'end_data_submit_date': tc.local_date_string(self.end_data_submit_date), | |
| 547 | 551 | 'city': self.city, | 
| 548 | 552 | 'location': self.location, | 
| 549 | 553 | 'lat': self.lat, | 
| @@ -590,6 +594,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin): | ||
| 590 | 594 | 'end_date': tc.local_date_string(self.end_date), | 
| 591 | 595 | 'start_display_date': tc.local_date_string(self.start_display_date), | 
| 592 | 596 | 'end_display_date': tc.local_date_string(self.end_display_date), | 
| 597 | + 'start_data_submit_date': tc.local_date_string(self.start_data_submit_date), | |
| 598 | + 'end_data_submit_date': tc.local_date_string(self.end_data_submit_date), | |
| 593 | 599 | 'city': self.city, | 
| 594 | 600 | 'location': self.location, | 
| 595 | 601 | 'lat': self.lat, | 
| @@ -638,6 +644,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin): | ||
| 638 | 644 | 'end_date': tc.local_date_string(self.end_date), | 
| 639 | 645 | 'start_display_date': tc.local_date_string(self.start_display_date), | 
| 640 | 646 | 'end_display_date': tc.local_date_string(self.end_display_date), | 
| 647 | + 'start_data_submit_date': tc.local_date_string(self.start_data_submit_date), | |
| 648 | + 'end_data_submit_date': tc.local_date_string(self.end_data_submit_date), | |
| 641 | 649 | 'city': self.city, | 
| 642 | 650 | 'location': self.location, | 
| 643 | 651 | 'lat': self.lat, | 
| @@ -685,6 +693,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin): | ||
| 685 | 693 | 'end_date': tc.local_date_string(self.end_date), | 
| 686 | 694 | 'start_display_date': tc.local_date_string(self.start_display_date), | 
| 687 | 695 | 'end_display_date': tc.local_date_string(self.end_display_date), | 
| 696 | + 'start_data_submit_date': tc.local_date_string(self.start_data_submit_date), | |
| 697 | + 'end_data_submit_date': tc.local_date_string(self.end_data_submit_date), | |
| 688 | 698 | 'city': self.city, | 
| 689 | 699 | 'location': self.location, | 
| 690 | 700 | 'lat': self.lat, | 
| @@ -723,6 +733,16 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin): | ||
| 723 | 733 |  | 
| 724 | 734 |  | 
| 725 | 735 | class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin): | 
| 736 | + UNAUDITED = 0 | |
| 737 | + PASSED = 1 | |
| 738 | + UNPASSED = 2 | |
| 739 | + | |
| 740 | + AUDIT_STATUS = ( | |
| 741 | + (UNAUDITED, '未审核'), | |
| 742 | + (PASSED, '已通过'), | |
| 743 | + (UNPASSED, '未通过'), | |
| 744 | + ) | |
| 745 | + | |
| 726 | 746 | signup_id = ShortUUIDField(_(u'signup_id'), max_length=32, blank=True, null=True, help_text=u'活动报名唯一标识', db_index=True, unique=True) | 
| 727 | 747 |  | 
| 728 | 748 | user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) | 
| @@ -738,10 +758,12 @@ class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin): | ||
| 738 | 758 |  | 
| 739 | 759 | fields = JSONField(_(u'fields'), blank=True, null=True, default='[]', help_text=u'自定义报名字段') | 
| 740 | 760 |  | 
| 741 | - passed = models.BooleanField(_(u'passed'), default=False, help_text=u'是否通过') | |
| 761 | + audit_status = models.IntegerField(_(u'audit_status'), choices=AUDIT_STATUS, default=UNAUDITED, help_text=u'审核状态', db_index=True) | |
| 742 | 762 |  | 
| 743 | 763 | is_signin = models.BooleanField(_(u'is_signin'), default=False, help_text=u'是否已签到') | 
| 744 | 764 |  | 
| 765 | + is_read = models.BooleanField(_(u'is_read'), default=False, help_text=u'报名消息是否已读') | |
| 766 | + | |
| 745 | 767 | class Meta: | 
| 746 | 768 | verbose_name = _(u'会员活动报名信息') | 
| 747 | 769 | verbose_name_plural = _(u'会员活动报名信息') | 
| @@ -756,6 +778,7 @@ class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin): | ||
| 756 | 778 | @property | 
| 757 | 779 | def final_avatar(self): | 
| 758 | 780 | return self.avatar and self.avatar.replace(settings.QINIU_FILE_URL_BEFORE, settings.QINIU_FILE_URL_AFTER).replace(settings.QINIU_FILE_URL_BEFORE2, settings.QINIU_FILE_URL_AFTER) | 
| 781 | + | |
| 759 | 782 |  | 
| 760 | 783 | @property | 
| 761 | 784 | def data(self): | 
| @@ -767,7 +790,7 @@ class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin): | ||
| 767 | 790 | 'name': self.name, | 
| 768 | 791 | 'phone': self.phone, | 
| 769 | 792 | 'fields': json.loads(self.fields) if self.fields else [], | 
| 770 | - 'passed': self.passed, | |
| 793 | + 'audit_status': self.audit_status, | |
| 771 | 794 | } | 
| 772 | 795 |  | 
| 773 | 796 | @property | 
| @@ -783,7 +806,7 @@ class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin): | ||
| 783 | 806 | 'phone': self.phone, | 
| 784 | 807 | 'fields': json.loads(self.fields) if self.fields else [], | 
| 785 | 808 | 'is_signin': self.is_signin, | 
| 786 | - 'passed': self.passed, | |
| 809 | + 'audit_status': self.audit_status, | |
| 787 | 810 | } | 
| 788 | 811 |  | 
| 789 | 812 | class MemberActivityDataInfo(BaseModelMixin, BrandInfoMixin): | 
| @@ -2,7 +2,7 @@ | ||
| 2 | 2 |  | 
| 3 | 3 | from django.conf.urls import url | 
| 4 | 4 |  | 
| 5 | -from member import activity_mp_views | |
| 5 | +from member import activity_mp_views, lensman_activity_mp_views | |
| 6 | 6 |  | 
| 7 | 7 | # activity | 
| 8 | 8 | urlpatterns = [ | 
| @@ -22,8 +22,8 @@ urlpatterns += [ | ||
| 22 | 22 |  | 
| 23 | 23 | # activity data | 
| 24 | 24 | urlpatterns += [ | 
| 25 | - url(r'^member/activity/data/submit$', activity_mp_views.activity_data_submit, name='mp_member_activity_data_submit'), # 会员活动数据提交 | |
| 26 | - url(r'^member/activity/data/detail$', activity_mp_views.activity_data_detail, name='mp_member_activity_data_detail'), # 获取会员活动报名信息 | |
| 25 | + url(r'^member/activity/data/submit$', lensman_activity_mp_views.activity_data_submit, name='mp_member_activity_data_submit'), # 会员活动数据提交 | |
| 26 | + url(r'^member/activity/data/detail$', lensman_activity_mp_views.activity_data_detail, name='mp_member_activity_data_detail'), # 获取会员活动报名信息 | |
| 27 | 27 | ] | 
| 28 | 28 |  | 
| 29 | 29 |  | 
| @@ -36,3 +36,9 @@ urlpatterns += [ | ||
| 36 | 36 |  | 
| 37 | 37 | url(r'^member/activity/contribute/detail/lastest$', activity_mp_views.activity_contribute_detail_lastest, name='member_activity_contribute_detail_lastest'), | 
| 38 | 38 | ] | 
| 39 | + | |
| 40 | +#activity message | |
| 41 | +urlpatterns += [ | |
| 42 | + url(r'^member/activity/signup/message$', lensman_activity_mp_views.activity_signup_message, name='mp_member_activity_signup_message'), | |
| 43 | + url(r'^member/activity/signup/message/read$', lensman_activity_mp_views.activity_signup_message_read, name='mp_member_activity_signup_message_read'), | |
| 44 | +] |